Go ahead, go crazy and add all of the dev dependencies you need to build your package. Once you've done that, take the built package and put it into another container that has only the runtime dependencies.
The ideal use-case for this is compiling Go, since you end up with a 1GB build container and a 12MB single-binary production container if you compile with static linking. Just beware when going the FROM SCRATCH route that you get nothing to go with it, you can't shell into the container or run "ps" or "lsof" for debugging because none of those exist.
Your image processes run on the host anyway, so just `ps` or `lsof` from the host. I've never had to exec into a Go/scratch container.
You can’t do this if you don’t have access to and root privileges on the host.
Sure, multistage builds are useful, but you could always get the same features (and more) by making packages for whatever distribution you use and installing it in your container. I get that's it's not as easy as writing a shell script in your Dockerfile to build all your dependencies, but sometimes better solutions aren't free.
(Also this is one of the reasons why the layer model of deduplication is flawed, and why I'm working on improving it. You shouldn't have to care how large your logical image size is.)