Privoxy (and Proxomitron before it) were doing it 20 years ago, but never caught on because they're a PITA to setup and can't handle inline adverts. Pi-hole is new, but it's even more work to setup, and suffers the same limitations.
And as ad-blocking has become more popular the problems only gotten worse. It's unusual that I see any ads any more, but when I do it's always in an inline div or span with a "random" id or class name, essentially invisible to pi-hole.
The only downside is that its filtering language is regex-like, so basically the equivalent of "two netcats and a sed". I've contemplated writing a filter proxy that would parse HTML into a DOM, run filtering on that tree-structured representation using something XPath or XSLT-ish, and then reserialise the modified HTML to send to browsers, but never had the time to. I suspect performance wouldn't be great with such a setup, although with MITM TLS it's already doing a double-encrypt-decrypt and I don't find that slowing me down noticeably.
Then there's also Javascript trickery loaded with the page that do hostile things if ad servers aren't reachable, and extensions know how to detect and replace them.
I think the closer the blocker is to the user, the higher the fidelity of the blocking.
I don't know exactly how it works under the hood, though. If I block a div with text in it, I know the div is still downloaded, just not displayed. I don't know what happens in more complicated cases, like if I block a div that contains an img tag. I think it's smart enough to prune the img tag before the browser downloads it, but IDK for sure.
I vaguely recall Privoxy having some kind of content filtering, but when I tried it, it wasn't html/css/javascript aware, and only did regex based replacement.
My experience has been that it took about 30 minutes to setup and I don't see ads on the internet, nor do my family or team.
Thats what I meant by network level blocking doesn't work very well. Using uBlock Origin, I don't see YouTube ads.