Most assume a particular OS.
Most (but not all) complete programs assume a particular OS (or one OS
from a fixed set, using preprocessor conditionals). There's plenty of
library code which doesn't assume any specific OS, but much of it does
assume at least 32 bits for int and/or size_t (or, even if technically it
works on a 16-bit platform, in practice it won't be useful because it's
too wasteful of memory).
Those are not larger embedded systems.... many hare and have been far
larger for a decade or two. Eg defence, telecoms etc.
Larger. Not largest. Meaning: excluding the smallest systems (8/16-bit).
There are vastly more of these systems (both in number of different
applications and numbers in use) than the "typical" ones you mention.
The word "typical" referred to code, not platforms. Code aimed at 8-bit
and 16-bit systems is less common and more likely to be platform-specific.
On the other hand I do have libraries that are designed to be portable
across most 8,16 and 32 bit embedded systems
I don't doubt that such libraries exist, but they're much less common than
code which assumes a 32-bit (or better) target. Writing (and testing) code
which works on smaller platforms takes extra effort.
Practically anyone who can program has ready access to at least one 32-bit
(or 64-bit) system and a suitable toolchain. Fewer people have both ready
access to a suitable 8/16-bit system and a reason to ensure that their
code actually works on such.
Many of the libraries used on a Linux system can be compiled for Windows,
MacOSX or various other 32-bit targets with little or no changes. Very
little of it would compile (and be useful) on a 16-bit platform without
significant changes.