Теоретически можно. Я использовал для этого tagged pointers, указатель на header помечал младшим битом. Но зачем? Можно сделать container_from_iterator, но для списка оно получается будет O(N), чтобы найти end придется до него итерировать, полезно разве что для маленьких списков.
Ну и вообще кстати, в intrusive списках самый дешёвый вариант чаще всего это nullptr в качестве end. Листовая нода нужна в трёх случаях:
1. std reverse_iterator, чтобы работал end--
2. быстрый static contains - по ненулевому next можно сразу сказать в списке элемент или нет
3. static erase для двунаправленных списков если не хранить размер