The Rust standard library in its default config should not be used if you care about code size (std is compiled with panic/fmt and backtrace machinery on by default). no_std has no visible deps besides memcpy/memset, and is comparable to bare metal C.
I understand this, but that is a pain that you don't get with Zig. The no_std constraint is painful to deal with as a dev even with no dependencies and also means that if you're working on a target that needs small binaries, that the crates.io ecosystem is largely unavailable to you (necessitating filtering by https://crates.io/categories/no-std and typically further testing for compilation size beyond that).
Zig on the other hand does lazy evaluation and tree shaking so you can include a few features of the std library without a big concern.
Rustc does a good job of removing unused code, especially with LTO. The trick is to make sure the std library main/panic/backtrace logic doesn't call code you don't want to pay for.
IIRC there's also a mutex somewhere in there used to workaround some threading issues in libc, which brings in a bespoke mutex implementation; I can't remember whether that mutex can be easily disabled, but I think there's a way to use the slower libc mutex implementation instead.
Also, std::fmt is notoriously bad for code size, due to all the dyn vtable shenanigans it does. Avoid using it if you can.
Regardless, the only way to fix many of the problems with std is rebuilding it with the annoying features compiled out. Cargo's build-std feature should make this easy to do in stable Rust soon (and it's available in nightly today).