Как перезагрузить UITableView после dismiss другого ViewController'a?
Вам нужны обсерверы. Подробнее тут.
У кордаты они пугающие, я люблю от Realm. 

В обработке обсервера можно чекнуть изменения в старых и новых данных, переставить местами и удалить анимированно. 

Делегаты, нотификации, viewWillAppear - решения на грани костылей, да простит меня мой коллега.
Есть много способов это сделать.

Самый простой - обновлять таблицу при появлении CategoriesViewController:
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
}

Если нужно дополнительно добавлять какую-то информацию из AddCategoryVC, можешь держать CategoriesViewController в качестве делегата внутри AddCategoryVC. Для этого:
1) Описываешь протокол для делегата:
protocol AddCategoryVCDelegate: AnyObject {
    func addCategoryDismissed()
}
2) Хранить в AddCategoryVC делегата (его нужно будет задать при создании контроллера, это будет твой CategoriesViewController):
weak var delegate: AddCategoryVCDelegate?
3) И вызывать его в dismiss completion:
dismiss(animated: true) {
    self.delegate?.addCategoryDismissed()
}