Sometimes, (real or perceived) redundancy is a consequence of a business rule. In this case, the business rule is: "a statement that is issued to an account shall contain only transactions for branches that belong to that particular account."
To enforce that rule, you could try to come up with a database schema that makes it impossible to violate it, or enforce it explicitly with a constraint or trigger. And that seems to be easier with StatementHeader.AccountID. In Oracle, you could write something like this:
create or replace trigger statement_has_unique_account
before insert or update on Statement
referencing old as old new as new
for each row
declare
m integer;
n integer;
begin
select b.AccountID
into m
from Branch b
where b.ID = new.BranchID;
select s.AccountID
into n
from StatementHeader s
where s.ID = new.StatementID;
if m <> n then
raise_application_error(-1000, 'No way!');
end if;
end;
Without AccountID in StatementHeader, you'd have to write a comparison with all the other AccountIDs from all other Statements that share the same StatementID, resulting in a more complicated sequence of statements.
So i would keep AccountID as a foreign key in StatementHeader and enforce the business rule explicitly with a trigger.