You can use new feature of KTable KTable.suppress in version 2.1
This method allows you get exactly one final result per window/key for windowed computations.
More about suppres
in KIP-328
You can update your implementation with suppress
like this:
KTable<Windowed<Long>, Counter> ret = input.groupByKey()
.windowedBy(TimeWindows.of(Duration.of(10, SECONDS)))
.aggregate(Counter::new, (k, v, c) -> new Counter(c.count + v.getDimension()))
.suppress(untilWindowCloses(BufferConfig.unbounded()));
ret.toStream().to("output"); // now stream should flush events to the output topic only when the window closes