* yes, I know ‘low-level’ is a subjective term
I used to work in the embedded world, and there C has historically been considered a "high-level" language for many platforms. However, we have started to see languages like C# and Python make their way into the world of tiny micros thanks to more power coming to the platforms themselves and the clever work being done by MicroPython and Microsoft.Then again some people will say anything. It's how things are used in practice that matters.
Garbage collection traditional means you can't meet hard latency contracts. And by definition you have no control over where garbage collected objects are in memory.
This is where the term "low level" is a bit ambiguous and relative. If you're trying to bit bang some serial protocol on a microcontroller with tight timings, C# and the GC are going to give you a hard time. But even C might give you a hard time here. I've had to drop down to inline assembly because it's much easier to count the cycles it'll take and insert a few nops where necessary to get the timing right.
Then, if you're on a non-realtime OS like Windows or Linux, no language is going to give you hard latency constraints.
Going further, it would be difficult to bit bang with tight timing constraints on x86 altogether due to speculative execution.
So from that perspective, C, x86, and modern operating systems might all be too high level to achieve your goal.
But for other goals, you might have a different answer. One interesting example was Xbox 360 games.
Game developers have traditionally used C++, because they have performance and latency constraints: if you're targeting 60 fps, you don't want any frames taking more than 16.6 ms. Indie developers had to use C# to make games for the 360. Unfortunately, the .Net Compact Framework it used had an old, slow, non-generational GC, which would cause hitches. So games would do one of two things to avoid hitches. Either they'd design their games to make zero allocations per frame, or they'd design their memory layout to be very simple so the GC would run fast. Structs are very helpful here because they don't generally allocate on the heap.
So was C# low level enough for game development on the Xbox 360? I'd say mostly. It gave you some hassle with the GC, but ultimately you had enough control over performance and latency to make it work.
If you're inputting hand assembled hex, then an assembler is high level. If you writing ASM, C is high level.
C is now thought of as low level, I'm sure many formerly 'high' level languages will become low level also.