Я новичок, поэтому у меня сейчас мышление не "а почему бы нет", а именно "а как он это сделал" ;)
Соответственно, у нас есть анонимный объект, у которого есть одна property. Этот объект создается в блоке return. Я не понимаю, почему эта property становится доступной для использования в качестве property для внешней функции budgetController.
1) Значением BudgetController становится то, что вернёт анонимная функция, это называется iife, "немедленно выполненое функциональное выражение", то есть, была объявлена анонимная функция и тут же выполнена, а то, что она вернула было присвоено переменной BudgetController
2) Теперь к тому, что эта функция делает. Она возвращает объект с одним методом, publicTest
3) Исходя из п.1 в переменной BudgetController лежит объект с одним методом publicTest
4) Ты его и вызываешь BudgetController.publicTest()
5) Функция add не содержалась в объекте, который был возвёрнут из iife, следовательно, её нет в обхекте, который лежит в BudgetController, следовательно, ты и не можешь его вызвать через BudgetController.add()