I would add to the low level direct memory pile anything needing DMA, anything with short deadline real time constraints, anything running without an OS where the peripherals are registers mapped into the memory map, and anything that needs to be deterministic (To the point of running from non cachable memory sometimes!).
C & C++ undoubtedly get used way outside the appropriate application domains, with C++ adding the fun of a leaky, fragile and complex set of abstractions, but actually there is a reason people still write in those languages that goes way past inertia. And some of us just like a language that (like Latin) stays still for years at a time.
If you are doing systems on small cores (Maybe a dozen kB of flash and a few kB of RAM), as I see it your choices are C and assembler, with maybe a very stripped down C++ as a third contender, what else is there that will actually let me deal with the memory mapped peripherals in a sane way?
Go and Rust will be taken seriously when there is a defined language that does not change every other month, and when there are a few different compilers implementing that defined language (Also a defined ABI for the common platforms would be nice).
Incidentally, GCs are right out! Reference count if you must, but garbage collection does bad things to realtime code (Yes I know bounded GCs exist, comment still usually stands with real implementations).
Personally, I favour the old embedded guys approach, figure out how many of what size at compile time and statically allocate the lot! You can still run off the end, but there will be no 'use after free' if you never free anything!
For date and time stuff, "Calendrical Calculations" is still my goto reference, but mixing UTC and well **Anything else** is just always going to be a source of pain.
Regards, Dan.