- Languages with class-level privacy almost always provide ways to work-around it - for example with introspection. Are these workarounds necessary, in that their absence would make certain problems much harder to solve in the language
Reflection and introspection are particularly useful in white-box testing, so as to ensure code coverage and implementation requirements. For this, access relaxation in reflection is necessary. Language-level tools (depending on the runtime) may also make use of reflection (imagine a native debugger which needs to access private fields).
Some would argue that if a class is properly designed, white-box testing (hence, access relaxation) of the private interface isn't necessary. Since an object's interactions with other objects is defined by its public interface (or, in the case of relatives, its public & protected interfaces), the private interface is immaterial. If the class is so complex as to require testing the private interface to ensure stability, the argument goes, then the class likely has too many responsibilities and should be refactored into multiple classes.
In some cases, casting in C++ can be used to access private fields, but this isn't an intended use.
Inheritance can be used to relax access restrictions, but this isn't a workaround so much as an intersection of access and inheritance rules, and is suggested by the LSP.
and if so, doesn't that indicate that the privacy paradigm is flawed?
Note that white-box tests and debuggers aren't a part of the software's normal execution, so circumventing access rules doesn't (in these cases) negate their purposes.
In other words, do people (ab)use these mechanisms when they are provided, and why?
I'd consider this to be a separate question from the earlier one. People definitely abuse reflection and inheritance to improperly relax access. I'd say typically when it happens it's because there's a design flaw in the program (not the language), but that's more opinion than not.
Casting to circumvent private access is abuse.
Increasing access using inheritance is often (always?) abuse. Sometimes it's another kind of design flaw: naming collision, in this case arising when you override a private base method with an unrelated public method that happens to have the same name & signature.
- Class-level privacy is not object-level privacy (an object has access to private state of other objects if they are of the same class), and we don't know how to do the latter.
On the contrary, in Ruby, no instance variable is accessible to another instance, even of the same class; the same goes for private methods. The Ruby term is "instance-private", rather than "object-level private". The same is true of Eiffel and functional-OOP style (where objects are functions that take a message). Smalltalk has instance-private fields, but no true private methods. Scala supports instance-private members.
In general, accessing instance fields outside of an instance isn't syntactically possible in languages that purely use a messaging model rather than a method-call/member-access/slots model, so the former have instance-private fields, though the feature isn't necessarily exclusive to them.
See also "Why are private fields private to the type, not the instance?".
But why would we want to?
The same secondary reason as for all forms of information hiding: anything that can overwrite state is a potential bug source; limiting an object's surface as much as possible helps cut down on the number and locations of potential bugs.