Почему переопределение метода без virtual -- это не переопределение?
Переопределить можно в любом случае, хоть с virtual, хоть без.
Но тут важно что вам надо от переопределенного метода. Если вам нужно использовать полиморфизм, то нужно ставить virttual, если нет - то нет.

Например дополним ваш пример функцией:
void func(struct A &a)
{
  a.fn();
}

int main() {
  B b;
  b.fn();
  func(b);
}
И передадим туда ссылку на b. Будет напечатана А, т.к. методы fn не виртуальные.
Если были бы виртуальные, то напечатается B - полиморфизм в действии.
Если в официальной доке с++ где-то написано "переопределение возможно тогда и только тогда, когда есть virtual у метода базового класса"
Написано, ровно это: eelis.net/c++draft/class.virtual#2

то почему именно так? 
Потому что это определение термина function override в C++. Для других вариантов взаимодействия имён функций есть другие термины.