Mutability is rarely needed and often makes things more complicated than needed.
Now if you want to talk about specific languages, then I would generally agree with you about C++ and C, but then there are ways you can design a program in those languages to be thread-safe. With FP you're just choosing a different solution to the problem which comes with its own drawbacks in some cases.
I agree if you stay in purely functional programming languages you run into points that are solved better with mutability. However those parts of a program are small and most parts are expressed better by pure functions.
Thread safety can't be expressed or enforced and you can't grab a bunch of classes from somewhere and assume anything about their fitness for multi-threaded code.
Typically one has to carefully design a class for multi-threaded use. Reasoning about state inside objects then quickly becomes infeasible.
What's a couple orders of magnitude of performance and some heavyweight link time dependencies between objects?
I don't really see how threading has anything to do with it.
What OOP allows you to do is choose what terms you want to express your solution in. You can choose language that exposes thread-safe aspects of your problem domain without requiring the user to be aware that they are expressing things in thread-safe terms. In my last project one of the early elements of our architecture was a thread-safe message queue for each thread to receive messages from across the thread boundary. Discussions on our team involved talk of messaging and threading because those were the abstractions we chose to use to express our solution.
We knew that order of access was important and so we chose to make it explicit in the language we used to express the problem. And the abstraction we chose allowed us to hide the details of the problem in such a way that we did not have to worry about memory protection as long as we were consistently using the architecture we built. That was a concern of the messaging system's maintainer. We could just as easily have chosen rows and columns and operators on such and expressed the same solution in those terms. What mattered to us was making sense of the problem, domain and solution.
It really doesn't matter which paradigm you use. What matters more is that you express your solution in terms that are consistent with the problem domain, and that you actually make an effort to understand the problem you're trying to solve well enough to express the solution. Anything beyond that is just sugar.