I find interesting though that the Rust code that generates a larger binary is about as complex and lengthy as the C code, while the Rust code which generates a smaller binary is clearly clunky and nobody would ever use it.
Of course it is a toy example and I imagine in most real-world examples the size of the binary is a moot point.
As for the part that removes libstd it's how you'd generally do it for a bare metal program (i.e. bootloader/OS) since you can't really use it without an OS unless you manually reimplement all sorts of primitives (memory allocations being the most obvious one).
Now if you do use libstd it's true that it's significantly larger that libc, but it's also vastly more powerful. You don't have anything like String, Vec or iterators in libc for instance, just a bunch of relatively low-level functions and wrappers around syscalls. It's also a fixed cost, so obviously for a simple Hello World there's a massive overhead but for a more complex application it should be less noticeable.
I mean when you think about it even the C Hello World is ridiculously bloated. If you were to write the equivalent program in assembly without any dependency on the libc you could probably get a binary that would be significantly smaller (and most of its size would really be the ELF metadata).
Why do Rust programs have larger binary sizes than C programs?