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.
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.
Thats what I meant by network level blocking doesn't work very well. Using uBlock Origin, I don't see YouTube ads.
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.
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.