Based on your history and preferences, you have a particular view about what it means to be a programmer. I have somewhat the same history, but come to a different conclusion. Start with a high level language, probably either a good OOP language (Java, Python, Scala...) or a good functional language (Scheme, Racket, ...). Those two groups of languages cover much, though not all, of the "higher level thinking" in programming today.
Programming Languages are all about abstraction. Different languages offer different kinds of abstractions and different levels of abstraction. However, once you choose a language, the programs that you build within that language are usually (always?) about creating even higher level abstractions than those in the base language. We try to write programs "in the language of the problem we are solving" and choose names (abstractions) accordingly. That is why we don't name our variables v1, v2, etc and our functions f1, f2, etc in our programs. Our variables are things like size and done and function names are like compute_capacity.
Every programmer needs to know something at least of a whole range of abstractions. Assembly language is very low, C is a bit higher. Ruby is quite high, as is Racket. Wherever you start learning you will eventually, after totally grokking that language, want to go to other levels. If you start at a low level then you have only one direction to move, but if you start at a higher level you can move both higher an lower. Thus you can learn how things are represented (at a low level) and how things might be hidden/regularized at a higher level.
Each programming language that you learn is built on a set of ideas that encapsulate what a program should look like. The view of a C program is very different from that of a Java program. The difficulty in moving upwards in the abstraction scale is that it is often difficult to give up the low-level constructs that you have become used to for others that are more appropriate in the new language. For example, polymorphism exists in most languages. In low level languages like C, the polymorphism is ad-hoc, implemented by setting and testing flags. In a higher level language (Java), polymorphism can be implemented more directly using certain design patterns (Strategy/Decorator) and helper objects. But the programs written by those who started low, too often still use only ad-hoc methods, which potentially leads to programs that are difficult to read and understand (too-deep nesting of structures).
You say you can learn any language using the "paradigms of C++". I know a few programmers who can validly say that, but most C++ programmers cannot, outside a fairly narrow range of languages. Moving from C++ to Scheme or Standard ML, for example, requires a completely new way of thinking about programs. Adopting this new way of thinking is actually inhibited by what you learned well in C++. Not that it is impossible, but it is a harder climb.
Let me give an analogy. If you want to become a medical doctor, you don't start by gathering herbs and chanting ancient songs. You don't, then, progress to leeches and bloodletting, following an historical trail. It is true, however, that some medical practice is only considered valid because it was handed down from antiquity but actually has no scientific basis. At some point in history, something was tried and it worked. No one knew why, but it became standard practice. But, and the point is, you don't need to start your medical training with ideas from 100 or 1000 years ago, even though many of the things learned then are still valid today. Nor do you need to start your education at a low level.
One misconception that people often have about high level languages is that they can only be understood in terms of some (supposed) implementation in a lower level language. Certainly compilers take this view, but humans don't need to. If a language is minimally useful it will provide a complete set of abstractions that permit you do any computation (Turing complete) solely within that set of abstractions. When I program in Java, I don't need to think about what the compiler will do with a reference variable (is it a pointer? is it like a pointer? is it completely different?). I just know that it gives me access to an object so that I can send messages to that object. I think in terms of reference and message, not in terms of pointer and function call and don't care if they are similar or distinct. In fact, thinking at the lower level can lead me astray. In a Java program, with overridden methods, it is not possible, in principle, to know which version of a method will be invoked without a complete trace of the program. You may not be able to discern the precise type of an object without that trace, and a distinct execution of the program may take a different path.
Some people think that low level languages are more efficient than high level languages. That may have been true at one time, but isn't necessarily true anymore. If you examine a few statements in a low level language, like C, they certainly seem to be easily implementable on a Von Neumann architecture. The problem is twofold. Programs consist of many many statements and it is easier to write and reason about complex algorithms in a high level language, especially one that is purpose built (bespoke) for that domain. Compilers today can execute tens of millions of instructions to globally optimize programs, something that a low level programmer can't do, and something that low level coding often inhibits. If I write a program describing explicitly how a problem is solved (typical in C), the optimizer is pretty much limited to following that instruction stream (not precisely, I realize, but that isn't global optimization). On the other hand, if a program describes what is to be accomplished rather than how to do it, an optimizer has many more options for coming up with both a high and low level set of strategies for execution.
The second reason that low level programs are only apparently efficient is that modern computers are only barely recognizable as Von Neumann architectures anymore. With multi-level cache (both data and instruction) and multi-processing on (say) graphics processors, the relation between the programmer notations (the program) and what is executed gets farther and farther apart as time goes on.
Summary:
Languages are about abstraction
A decent language will provide a (Turing) complete set of abstractions. Therefore you can think at that level of abstraction.
Lower level language are not, inherently, more efficient than higher level languages, though they may appear so. Compilers can do more than you think if you let them.
A human, moving to a new abstraction level, will have difficulties made more intense the more they are committed to the "old way of thinking".
Start somewhere. For myself (who started low), starting higher gives you a better, clearer path. But you will eventually want to branch out. Learn to think, completely, within the abstractions provided by the language you use. Understand those abstractions in terms of the other abstractions and idioms in that language, rather than by "mentally compiling" everything.
Here is an odd historical note about medicine, that I'm pretty sure doesn't really apply here:
In a few cases it isn't ethical anymore not to use some relatively ancient practice, so science is blocked from advancement in that area. The Pasteur Treatment for rabies is like that. It works, but is a dreadful process for the patient. But rabies is nearly always fatal, so it is unethical to set up a scientific experiment in which the control group gets Pasteur, but the experimental group gets (only) a vaccine.