One way to classify programming languages is by their abstractions (specifically, by the complexity of their abstractions, or how far those abstractions are from how the hardware works in reality). (I actually prefer to classify programming languages by their paradigm, but bear with me here.)
At the lowest level, you have assembly languages, which are just different symbolic representations of the underlying machine code, with trivial abstractions like labels instead of addresses.
(Anything above that level is up to discussion, however; depending on how you define the complexity of abstractions.)
At the next level, you have low-level programming languages. Nowadays (among actively-used programming languages), this includes C, Forth, and Fortran at least.
If we look at freestanding C, we find that it is an extremely simple and compact programming language, with its abstractions more like compatibility layer between different hardware architectures rather than abstractions that help human programmers. In comparison, Forth is more abstract, as it behaves like a stack-based abstract computer. And Fortran has all sorts of abstractions, including array slicing, that are not "natively" supported by hardware, whose intent is to make "programming" something humans can do without knowing how computers actually work.
In a very real way, freestanding C is the "simplest" portable programming language we have.
In that sense, it is obvious how and why C is still being used. It is nowhere near perfect, as its "abstractions" – more like hardware compatibility features, really – no longer match the hardware, the hardware having vastly progressed forward, but the low-level programming languages staying stagnant, or just adding to instead of refining their abstractions/compatibility layers... which should also explain the reason for my own rant at C standard development in this thread.