The default is contained in the egg or wheel.
$ ls ~/.pyenv/versions/trac-2.7/lib/python2.7/site-packages/Trac-1.4.2-py2.7.egg/trac/ticket/templates/ticket_notify_email.txt
/Users/rjollos/.pyenv/versions/trac-2.7/lib/python2.7/site-packages/Trac-1.4.2-py2.7.egg/trac/ticket/templates/ticket_notify_email.txt
A template in $env/templates with the same name as a Trac or plugin templates will override Trac or the plugin, but in general, it's not recommended because you need to re-apply your changes each time the template changes in an upgrade.
ticket_notify_email.txt, is a special case in that it doesn't change very often. But good to keep a diff or your changes so you can apply them to a copy of a new template after upgrade.
I'm working this week on upgrading a Trac site in which the previous maintainer had made copies of various templates like wiki_view.html in an earlier version of Trac, probably 1.0.3. The templates were all customized. Now they are on Trac 1.0.9 and several features are broken because they are serving modified versions of 1.0.3 templates. I'm talking them to 1.0.20, then hopefully 1.2.6 and 1.4.2 eventually. Things would get worse and worse if we continued using 1.0.3 templates through those upgrade steps.
The next step is to go through all those templates and diff them, figure out what the customizations are, and hopefully implement those the right way: via ITemplateStreamFilter (deprecated in Trac 1.4) or JavaScript.
Customizing the notification template is probably the most typical use case for $env/templates. You are right, the tricky thing is to know how to get the template and copy it there. You can fetch it from the Trac repository or copy it from the install location if you know where to find it.
We could consider adding a trac-admin command.
trac-admin $env extract_template ticket_notify_email.txt
But per my example, we don't want to make it too easy for users to customize templates, at least without making the warnings about the risks much more prominent and frequent.