Option 1
It is possible that the inserted reference is not allowed here because SQL Server does not have access to the value actually inserted by the instead of trigger on the view.
SQL Server instead-of triggers are implemented by writing information about the changes that would occur as a result of the triggering statement to worktables (one for inserts, one for deletes).
Instead-of triggers do not use row versioning, like after triggers do. These worktables are fully populated by the triggering statement before the trigger fires.
The OUTPUT clause is part of the triggering statement. The query plan for that statement only has access to values that exist at that time. The instead-of trigger fires afterward. Logically, the output clause cannot return values that have not been computed yet. You can see all this in the execution plans for your example:

In your implementation, the instead-of trigger essentially does nothing other than a regular insert would do, but that isn't guaranteed to be the case. An instead-of trigger can do anything it likes instead of the triggering action, including doing nothing.
You can get the statement to 'work' by referencing the source column value, but again this will only represent the actually inserted value if the instead-of trigger happens to do the same thing:
declare @inserted1 table ([id] uniqueidentifier);
merge vwTbl using (
values (newid(), 'xxx')
) as i (id, data) on 1=0
when not matched then
insert (id, data)
values (i.id, i.data)
output i.id -- CHANGED
into @inserted1;
select * from @inserted1
db<>fiddle demo
There is nothing you can do to change your view's instead of trigger so this pattern will work right now.
Option 2
On the other hand, it is also completely conceivable this is unintended behaviour. There have been many such cases with MERGE.
The equivalent statement written as an INSERT does work:
declare @inserted1 table ([id] uniqueidentifier);
INSERT dbo.vwTbl (id, data)
OUTPUT Inserted.id
INTO @inserted1 (id)
VALUES (NEWID(), 'xxx');
This follows the documented OUTPUT semantic for the inserted pseudo-table in this case (emphasis added):
INSERTED
Is a column prefix that specifies the value added by the insert or update operation. Columns prefixed with INSERTED reflect the value after the UPDATE, INSERT, or MERGE statement is completed but before triggers are executed.
If MERGE worked the same way as INSERT here, your statement would work as expected and the OUTPUT clause would return the pre-trigger value. It is possible this is a deliberate design change. There was more than one of those made when MERGE was introduced.
On the other hand, the MERGE statement works as desired if the instead-of trigger is on the base table rather than a view (demo), so the current behaviour is inconsistent if nothing else.
The chance that this is a bug is increased by noting that it is possible to reference the deleted pseudo-table in your example, though it returns a null result, naturally. See this demo. The inference here is that the parser is getting confused about the resulting action (an insert, not a delete).
If you require a definitive answer, your best bet might be to open a support case with Microsoft.